package com.sharemarking.application.common.service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;

import com.sharemarking.application.common.dto.MenuDto;
import com.sharemarking.application.common.dto.UserDetailImpl;
import com.sharemarking.application.common.entity.Menu;
import com.sharemarking.application.common.entity.Permission;
import com.sharemarking.application.common.entity.Role;
import com.sharemarking.application.common.entity.User;
import com.sharemarking.application.common.repository.MenuRepo;
import com.sharemarking.application.common.repository.UserRepo;

@Service
public class MenuService {
	
	@Autowired
	private UserRepo ur;
	
	@Autowired
	private MenuRepo mr;
	
	public static final GrantedAuthority adminAuthority=new SimpleGrantedAuthority("ROLE_ADMINISTRATOR");
	
	public Iterable<Menu> findAllMenus(){
		return mr.findAll(new Specification<Menu>(){
			@Override
			public Predicate toPredicate(Root<Menu> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				return cb.equal(root.get("delFlag").as(Boolean.class), false);
			}
			
		},new Sort("sort"));
	}
	/**
	 * 用于新增、修改菜单的下拉选择框
	 * @return
	 */
	public List<Menu> getAllMenus(){
		return getOrderedChildren(0, findAllMenus());
	}
	/**
	 * 将子菜单取出并排序
	 * @param parentId 父菜单id
	 * @param menus 已按sort排序的菜单
	 * @return
	 */
	private List<Menu> getOrderedChildren(Integer parentId,Iterable<Menu> menus){
		List<Menu> target=new ArrayList<Menu>();
		for(Menu menu:menus){
			if(menu.getParentId().equals(parentId)){
				target.add(menu);
				target.addAll(getOrderedChildren(menu.getId(),menus));
			}
		}
		return target;
	}
	/**
	 * 用于菜单页
	 * @return
	 */
	public List<MenuDto> getMenus(){
		Authentication om=SecurityContextHolder.getContext().getAuthentication();
		boolean isAdmin=om.getAuthorities().contains(adminAuthority);
		Iterable<Menu> menus=findAllMenus();
		if(!isAdmin){
			UserDetailImpl udi=(UserDetailImpl)om.getPrincipal();
			User user=ur.findOne(udi.getId());
			List<Permission> permissions=new ArrayList<Permission>();
			List<Role> roles=user.getRoles();
			for(Role role:roles){
				permissions.addAll(role.getPermissions());
			}
			List<Menu> target=new ArrayList<Menu>();
			for(Menu menu:menus){
				if((menu.getPermission()&Menu.PERMISSION_READ)==0){
					target.add(menu);
				}else{
					for(Permission p:permissions){
						if(p.getMenu().equals(menu)){
							if((p.getPermission()&Menu.PERMISSION_READ)>0)target.add(menu);
							break;
						}
					}
				}
			}
			menus=target;
		}
		List<MenuDto> target=getChildren(0,menus);
		return target;
	}
	/**
	 * 获取子菜单
	 * @param parentId
	 * @param menus
	 * @return
	 */
	private List<MenuDto> getChildren(Integer parentId,Iterable<Menu> menus){
		List<MenuDto> target=new ArrayList<MenuDto>();
		for(Menu menu:menus){
			if(menu.getParentId().equals(parentId)){
				MenuDto menuDto=new MenuDto();
				menuDto.setId(menu.getId());
				menuDto.setHref(menu.getHref());
				menuDto.setName(menu.getName());
				menuDto.setIcon(menu.getIcon());
				menuDto.setTarget(menu.getTarget());
				menuDto.setSort(menu.getSort());
				menuDto.setChildren(getChildren(menu.getId(),menus));
				target.add(menuDto);
			}
		}
		target.sort(new Comparator<MenuDto>(){
			@Override
			public int compare(MenuDto arg0, MenuDto arg1) {
				return arg0.getSort()-arg1.getSort();
			}
		});
		return target;
	}
}
